package com.intelligent.ispc.common.persistence.jdbc;

import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SQLServer2008Dialect;
import org.hibernate.engine.spi.RowSelection;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Peter on 15/11/25.
 */
public enum JDBCPageDialect {
    MYSQL {
        @Override
        public String generatePageSql(String sql, JdbcPageable page) {
            StringBuffer pageSql = new StringBuffer(sql);
            if (page != null) {
                pageSql.append(" LIMIT " + page.getBegin() + "," + page.getSize());
            }
            return pageSql.toString();
        }

        @Override
        public void setDateDialect() {
            // TODO mysql datetime dialect
        }

    },
    ORACLE {
        @Override
        public String generatePageSql(String sql, JdbcPageable page) {
            StringBuffer pageSql = new StringBuffer(sql);
            if (page != null) {
                pageSql.insert(0, "SELECT * FROM (SELECT tmp_tb.*, ROWNUM row_id FROM (")
                        .append(") tmp_tb WHERE ROWNUM")
                        .append(page.getBegin());
            }
            return pageSql.toString();
        }

        @Override
        public void setDateDialect() {
            // TODO oracle datetime dialect

        }

    },
    SQLSERVER {
        @Override
        public String generatePageSql(String sql, JdbcPageable page) {
            String newSql = sql;
            String orderBy = null;

            int orderIndix = newSql.toUpperCase().indexOf("ORDER");
            if (orderIndix != -1) {
                orderBy = newSql.substring(orderIndix);
                newSql = newSql.substring(0, orderIndix);
            }

            if (page != null) {
                Dialect dialect = null;
                dialect = new SQLServer2008Dialect();
                RowSelection rs = new RowSelection();
                rs.setFirstRow(1);
                rs.setMaxRows(2);
                newSql = dialect.getLimitHandler().processSql(newSql, rs);
                newSql = this.setPageParam(newSql, page);
            }
            if (orderIndix != -1) {
                newSql = newSql.replaceFirst("ORDER BY CURRENT_TIMESTAMP", orderBy);
            }
            return newSql;
        }

        @Override
        public void setDateDialect() {
            dateDialect.put("castDateTime", "cast('{0}' as datetime)");
            dateDialect.put("convertTime", "convert(varchar(50),{0},120)");
        }

    };

    protected String setPageParam(String sql, JdbcPageable page) {
        StringBuilder sb = new StringBuilder(sql);

        sb.replace(sb.lastIndexOf("?"), sb.lastIndexOf("?") + 1, +page.getEnd() + 1 + "");
        sb.replace(sb.lastIndexOf("?"), sb.lastIndexOf("?") + 1, page.getBegin() + 1 + "");
        return sb.toString();
    }

    public abstract String generatePageSql(String sql, JdbcPageable page);

    public abstract void setDateDialect();

    public static final Map dateDialect = new HashMap();
}
